package com.om.common;

/**   
* @CopyRright (c) 
* @Title:MySqlBeanFactory.java
* @Description: 实现了My Server的分页查询以及执行存储过程查询
* @author tangchuan
* @version V1.0   
*/ 

import com.om.base.AbstractBean;
import com.om.base.BeanFactory;
import com.om.base.SqlFilter;
import com.om.base.Utils;
import com.om.pages.PageInfo;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class MySqlBeanFactory extends BeanFactory {
	
	public <T> List<T> getBeanList(Class<?> beanClass,SqlFilter filter, PageInfo page) {
		String sql = "";
		List<T> beanList = null;
		int startIndex = page.pageSize * page.currentPage;

		//beanList = getBeanList(beanClass, filter, startIndex, page.pageSize);
		if(!"".equals(page.orderBy)){
			this.orderBy = page.orderBy;
		}
		beanList = getBeanList(beanClass, filter, startIndex, page.realSize);
		return beanList;
	}

	public <T> List<T> getBeanList(SqlFilter filter, String orderBy) {
		List<T> beanList = null;
		String sql = "";
		String className = "";
		PreparedStatement pst = null;
		java.sql.CallableStatement call=null;
		ResultSet rs = null;
		try {
			beanList = new ArrayList<T>();
			if(this.connection ==null){
				this.connection = Utils.GetOpenedConnection();
			}
			this.bean.setDefaultOrderByExpress(orderBy);
			sql = bean.generateQuerySql(filter);
			
			className = this.bean.getClassName();
			Pattern p = Pattern.compile("(\\$|@)\\{\\w+\\}");
			Matcher m = p.matcher(sql);
			if(m.find()){
				filter.removeAll();
			}
			
			if (filter == null) {
				filter = new SqlFilter();
			}
			if(sql.indexOf("CALL")==-1){
				AdjustFilter(filter);
			}
		
			sql = bean.generateQuerySql(filter);
			if(this.selectColumns!=null && !"".equals(this.selectColumns)){
				sql = sql.replace("*", this.selectColumns);
			}
			
			Pattern p1 = Pattern.compile("order\\s+by");
			Matcher m1 = p1.matcher(sql.toLowerCase());
			if (orderBy != null && !m1.find()) {
				sql += orderBy;
			}
			
			List<String> lstField = filter.getFieldList();
			List lstValue = filter.getValueList();
			
			if(sql.indexOf("CALL")!=-1){
				call = this.connection.prepareCall(sql);
		
				call = prepareCallableStatement(sql,filter);
				rs = call.executeQuery();
			}
			else {
				pst = prepareSql(sql, lstField, lstValue);
				rs = pst.executeQuery();
			}
			
			
			
			ResultSetMetaData met = rs.getMetaData();
			while (rs.next()) {
				AbstractBean item = (AbstractBean) Class.forName(className)
						.newInstance();
				if (item.Field.length == 0) {
					item.Field = new String[met.getColumnCount()];
					for (int i = 0; i < met.getColumnCount(); ++i) {
						String column = met.getColumnLabel(i + 1);
						item.Field[i] = column;
					}
				}
		
				AbstractBean.CopyConfig(bean, item);
				
				Pattern p2 = Pattern.compile("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}");
				for (int i = 0; i < item.Field.length; ++i) {
					Object value = null;
					String columnName = item.Field[i];
					String columnTypeName = met.getColumnTypeName(i + 1);
					if (columnTypeName.indexOf("BLOB") != -1) {
						value = rs.getAsciiStream(columnName);
					} else if (columnTypeName.indexOf("TINYINT") != -1) {
						value = rs.getShort(columnName);
					
					} 
					else if(columnTypeName.toLowerCase().indexOf("datetime")!=-1){
						value = rs.getObject(columnName);
						if(value!=null){
							Matcher match = p2.matcher(value+"");
							if (match.find()) {
								value = match.group(0);
							}
						}
						
					} 
					else {
						value = rs.getObject(columnName);
					}

					item.set(columnName, value);
				}
				
				item.set(AbstractBean.KEY_VALUE, item.getKeyValue());
				item.afterLoad();
				beanList.add((T) item);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return beanList;
	}

	public <T> List<T> getBeanList(Class<?> beanClass, SqlFilter filter, int startIndex, int pageSize) {
		List<T> beanList = new ArrayList<T>();
		PreparedStatement pst = null;
		String className = "";
		ResultSet rs = null;
		String sql = "";
		try {
			className = beanClass.getName();
			bean = (BaseBean) Class.forName(className).newInstance();
			bean.connection = this.connection;
			bean.initColumns();
			
			this.bean.setDefaultOrderByExpress(orderBy);
			this.bean.setDefaultStartIndex(startIndex);
			this.bean.setDefaultPageSize(pageSize);
			sql = this.bean.generateQuerySql(filter);
			if(this.selectColumns!=null && !"".equals(this.selectColumns)){
				sql = sql.replace("*", this.selectColumns);
			}
			Pattern p = Pattern.compile("(\\$|@)\\{\\w+\\}");
			Matcher m = p.matcher(sql);
			if(m.find()){
				filter.removeAll();
			}
			if (filter == null) {
				filter = new SqlFilter();
			}
			if(!bean.TABLE_NAME.equals("")){
				AdjustFilter(filter);
			}
			
			Pattern p1 = Pattern.compile("order\\s+by");
			Matcher m1 = p1.matcher(sql.toLowerCase());
			
			if (orderBy != null && !m1.find()) {
				sql += orderBy;
			}
			if(!this.bean.usingLuceneQuery){
				sql = sql + " limit " + startIndex + "," + pageSize;
			}

			
			

			List<String> lstField = filter.getFieldList();
			List lstValue = filter.getValueList();

			pst = prepareSql(sql, lstField, lstValue);

			rs = pst.executeQuery();
			ResultSetMetaData met = rs.getMetaData();
			while (rs.next()) {
				try{
					AbstractBean item = (AbstractBean) Class.forName(className).newInstance();
					if (item.Field.length!=met.getColumnCount()) {
						item.Field = new String[met.getColumnCount()];
						for (int i = 0; i < met.getColumnCount(); ++i) {
							String column = met.getColumnLabel(i + 1);
							item.Field[i] = column;
						}
					}
					
					AbstractBean.CopyConfig(bean, item);
					
					Pattern p2 = Pattern.compile("\\d{4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}");
					for (int i = 0; i < item.Field.length; ++i) {
						Object value = null;
						String columnName = item.Field[i];
						String columnTypeName = met.getColumnTypeName(i + 1);
						if (columnTypeName.indexOf("BLOB") != -1) {
							value = rs.getAsciiStream(columnName);
						} else if (columnTypeName.indexOf("TINYINT") != -1) {
							value = rs.getShort(columnName);
						} 
						else if(columnTypeName.toLowerCase().indexOf("datetime")!=-1){
							value = rs.getObject(columnName);
							if(value!=null){
								Matcher match = p2.matcher(value+"");
								if (match.find()) {
									value = match.group(0);
								}
							}
							
						} 
						else {
							value = rs.getObject(columnName);
						}
						item.set(columnName, value);
						
					}
					item.set(AbstractBean.KEY_VALUE, item.getKeyValue());
					item.afterLoad();
					beanList.add((T) item);
				}catch(Exception ex1){
					ex1.printStackTrace();
				}
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return beanList;
	}



	
	
}


